Completed
Pull Request — master (#20)
by Janis
02:37
created

View.renderFileAction   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 4
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
/**
2
 * nextCloud - ocr
3
 *
4
 * This file is licensed under the Affero General Public License version 3 or
5
 * later. See the COPYING file.
6
 *
7
 * @author Janis Koehr <[email protected]>
8
 * @copyright Janis Koehr 2016
9
 */
10
(function() {
11
	/**
12
	 * Constructor of the View object.
13
	 * This will update the different parts of the html.
14
	 * @param ocr
15
	 * @param filehandler
16
	 * @constructor
17
	 */
18
19
	// Handlebarsjs template
20
	var TEMPLATE_OCR_DROPDOWN = '<div id="ocrDropdown" class="ocrUserInterface">'+
21
		'{{#if noMatches}}'+
22
		t('ocr', 'No languages for tesseract available')+
23
		'{{else}}'+
24
		t('ocr', 'Select')+
25
		':'+
26
		'<select id="ocrLanguage">'+
27
		'{{#each languages}}'+
28
		'<option value="{{this}}">{{this}}</option>'+
29
		'{{/each}}'+
30
		'</select>'+
31
		'<input type="button" id="processOCR" value="'+
32
		t('ocr', 'Process')+
33
		'" />'+
34
		'{{/if}}'+
35
		'</div>';
36
37
	var TEMPLATE_OCR_SELECTED_FILE_ACTION = '<span class="selectedActionsOCR hidden">'+
38
		'<a id="selectedFilesOCR" href="" class="ocr">'+
39
		'<span class="icon icon-external"></span>'+
40
		'<span>'+t('ocr', 'OCR')+'</span>'+
41
		'</a>'+
42
		'</span>';
43
44
	var View = function (ocr) {
45
		this._ocr = ocr;
46
		this._selectedFiles = [];
47
		this._row = undefined;
48
	};
49
50
	/**
51
	 * Class prototype for the View. Following functions are available:
52
	 *
53
	 */
54
	View.prototype = {
55
		initialize: function () {
56
			this.renderSelectedActionButton();
57
			this.registerFileActions();
58
			this.registerEvents();
59
			this.loopForStatus();
60
		},
61
		destroy: function () {
62
			var self = this;
63
			self.destroyDropdown();
64
			self.destroySelectedActionButton();
65
			OCA.Files.fileActions.clear();
66
			OCA.Files.fileActions.registerDefaultActions();
67
		},
68
		registerFileActions: function () {
69
			var self = this;
70
			/**
71
			 * Register FileAction for mimetype pdf
72
			 */
73
			OCA.Files.fileActions.registerAction({
74
				name: 'Ocr',
75
				displayName: t('ocr', 'OCR'),
76
				order: 100,
77
				mime: 'application/pdf',
78
				permissions: OC.PERMISSION_UPDATE,
79
				altText: t('ocr', 'OCR'),
80
				iconClass: 'icon-external',
81
				actionHandler: function (filename, context) {
82
					var path = context.dir || context.fileList.getCurrentDirectory();
83
					var mimetype = context.fileActions.getCurrentMimeType();
84
					var type = context.fileActions.getCurrentType();
85
					self.renderFileAction(filename, path, type, mimetype);
86
				}
87
			});
88
			/**
89
			 * Register FileAction for mimetype image
90
			 */
91
			OCA.Files.fileActions.registerAction({
92
				name: 'Ocr',
93
				displayName: t('ocr', 'OCR'),
94
				order: 100,
95
				mime: 'image',
96
				permissions: OC.PERMISSION_UPDATE,
97
				altText: t('ocr', 'OCR'),
98
				iconClass: 'icon-external',
99
				actionHandler: function (filename, context) {
100
					var path = context.dir || context.fileList.getCurrentDirectory();
101
					var mimetype = context.fileActions.getCurrentMimeType();
102
					var type = context.fileActions.getCurrentType();
103
					self.renderFileAction(filename, path, type, mimetype);
104
				}
105
			});
106
		},
107
		setSelectedFiles: function (selectedFiles) {
108
			var self = this;
109
			self._selectedFiles = selectedFiles;
110
		},
111
		getSelectedFiles: function () {
112
			var self = this;
113
			return self._selectedFiles;
114
		},
115
		destroySelectedActionButton: function () {
116
			// remove the Template
117
			$('.selectedActionsOCR').remove();
118
		},
119
		renderSelectedActionButton: function () {
120
			// append the TEMPLATE to correct position
121
			$(TEMPLATE_OCR_SELECTED_FILE_ACTION).appendTo($('#headerName-container'));
122
		},
123
		destroyDropdown: function () {
124
			if ($('#ocrDropdown').length){
125
				$('#ocrDropdown').detach();
126
			}
127
		},
128
		renderDropdown: function(){
129
			var self = this;
130
			self.destroyDropdown();
131
			/** global: Handlebars */
132
			var template = Handlebars.compile(TEMPLATE_OCR_DROPDOWN);
133
			var noMatches = true;
134
			var languages = self._ocr.getLanguages();
135
			if(languages.length > 0 && typeof languages !== undefined){ noMatches = false; }
136
			return template({languages: languages, noMatches: noMatches});
137
		},
138
		renderFileAction: function (file, path, type, mimetype) {
139
			var self = this;
140
			var html = self.renderDropdown();
141
			$(html).appendTo($('tr').filterAttr('data-file',file).find('td.filename'));
142
			var files = [{name: file, path: path, type: type, mimetype: mimetype}];
143
			self.setSelectedFiles(files);
144
		},
145
		toggleSelectedActionButton: function () {
146
			var self = this;
147
			var selectedActionButton = $('.selectedActionsOCR');
148
			var selFiles = OCA.Files.App.fileList.getSelectedFiles();
149
			if(selFiles.length > 0 && typeof selFiles !== undefined){
150
				//show if all have correct mimetype and type = file
151
				if(self._ocr.checkMimeTypes(selFiles)){
152
					// show if not already shown
153
					selectedActionButton.removeClass('hidden');
154
				}else{
155
					selectedActionButton.addClass('hidden');
156
				}
157
			}else{
158
				// hide if not already hidden
159
				selectedActionButton.addClass('hidden');
160
				self.setSelectedFiles([]);
161
			}
162
		},
163
		hideSelectedActionButton: function () {
164
			var self = this;
165
			var selectedActionButton = $('.selectedActionsOCR');
166
			selectedActionButton.addClass('hidden');
167
			self.setSelectedFiles([]);
168
		},
169
		togglePendingState: function (force, initialcount) {
170
			var self = this;
171
			var html = '';
172
			var pendingcount = self._ocr.getStatus().pending;
173
			if(force){
174
				html = '<span class="icon icon-loading-small"></span>&nbsp;<span>' + n('ocr','OCR started: %n currently pending file in queue.', 'OCR started: %n currently pending files in queue.', initialcount) + '</span>';
175
			}else{
176
				html = '<span class="icon icon-loading-small"></span>&nbsp;<span>' + ' ' + n('ocr','OCR: %n currently pending file in queue.', 'OCR: %n currently pending files in queue.', pendingcount) + '</span>';
177
			}
178
			if(pendingcount > 0 || force){
179
				if (self._row !== undefined) { OC.Notification.hide(self._row); }
180
				self._row = OC.Notification.showHtml(html);
181
			}else{
182
				if (self._row !== undefined){
183
					OC.Notification.hide(self._row);
184
					self._row = undefined;
185
				}
186
			}
187
		},
188
		updateFileList: function () {
189
			var self = this;
190
			OCA.Files.App.fileList.reload();
191
			self.toggleSelectedActionButton();
192
		},
193
		/**
194
		 * Loops as long as there are pending objects
195
		 */
196
		loopForStatus: function () {
197
			var self = this;
198
			$.when(self._ocr.checkStatus()).done(function(){
199
				if(self._ocr.getStatus().failed > 0) { self.notifyError(n('ocr', 'OCR processing for %n file failed. For details please contact your administrator.', 'OCR processing for %n files failed. For details please contact your administrator.', self._ocr.getStatus().failed.length)); }
200
				if(self._ocr.getStatus().pending > 0){
201
					if(self._ocr.getStatus().processed > 0) { self.updateFileList(); }
202
					self.togglePendingState(false);
203
					setTimeout($.proxy(self.loopForStatus,self), 4500);
204
				}else{
205
					if(self._ocr.getStatus().processed > 0) { self.updateFileList(); }
206
					self.togglePendingState(false);
207
				}
208
			}).fail(function(message){
209
				self.notifyError(message);
210
				setTimeout($.proxy(self.loopForStatus,self), 4500);
211
			});
212
		},
213
		notifyError: function (message) {
214
			/** global: OC */
215
			OC.Notification.showHtml('<div>'+message+'</div>', {timeout: 10, type: 'error'});
216
		},
217
		registerEvents: function(){
218
			var self = this;
219
			// Close on click on other element
220
			$(document).click(function(event) {
221
				if(!$(event.target).closest('#ocrDropdown').length) {
222
					self.destroyDropdown();
223
					self.setSelectedFiles([]);
224
				}
225
			});
226
			// Register submit action
227
			$(document).on('click', '#processOCR', function(){
228
				var selectedLanguage = $('#ocrLanguage').val();
229
				$.when(self._ocr.process(self.getSelectedFiles(), selectedLanguage)).done(function(){
230
					self.destroyDropdown();
231
232
					// status monitoring init
233
					self.togglePendingState(true, self.getSelectedFiles().length);
234
					self.setSelectedFiles([]);
235
					setTimeout($.proxy(self.loopForStatus,self), 4500);
236
				}).fail(function(message){
237
					self.notifyError(t('ocr', 'OCR processing failed:')+ ' ' + message);
238
					self.destroyDropdown();
239
				});
240
			});
241
			// Register click selectedFilesAction
242
			$(document).on('click', '#selectedFilesOCR', function(){
243
				var html = self.renderDropdown();
244
				$(html).appendTo($('tr').find('th.column-name'));
245
				self.setSelectedFiles(OCA.Files.App.fileList.getSelectedFiles());
246
				return false;
247
			});
248
			// Register checkbox events
249
			/** global: _ */
250
			OCA.Files.App.fileList.$fileList.on('change', 'td.filename>.selectCheckBox', _.bind(self.toggleSelectedActionButton, this));
251
			OCA.Files.App.fileList.$el.find('.select-all').click(_.bind(self.toggleSelectedActionButton, this));
252
			OCA.Files.App.fileList.$el.find('.delete-selected').click(_.bind(self.hideSelectedActionButton, this));
253
		}
254
	};
255
	/** global: OCA */
256
	if (OCA.Ocr) {
257
		OCA.Ocr.View = View;
258
	}
259
})();